﻿// <copyright file="ToolsController.cs" company="Clever Software">
// Copyright (c) 2013, 2014 All Right Reserved, http://www.cleversoftware.by
//
// This source is subject to the Microsoft Permissive License.
// Please see the License.txt file for more information.
// All other rights reserved.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// </copyright>
// <author>Clever Software</author>
// <email>info@cleversoftware.by</email>
// <date>2014-02-04</date> 
// <summary>CleverCMS source code</summary>

namespace CleverCMS.Web.Controllers
{
    using System;
    using System.Web.Mvc;
    using System.Globalization;

    using Common.Logging;
    using Blog.Data.Entities;
    using Blog.Services;

    using CleverCMS.Core.Services;
    using CleverCMS.Core.Web.Filters;
    using CleverCMS.Core.Extensions;
    using CleverCMS.Cms.Services;
    using CleverCMS.Cms.Data.Entities;

    [HandleError]
    public class ToolsController : Controller
    {
        private readonly LoggingService     m_log;
        private readonly PageService        m_pageService;
        private readonly BlogEntryService   m_blogService;
        private readonly SettingService     m_settingService;

        public ToolsController(PageService      pageService, 
                               SettingService   settingService, 
                               LoggingService   log, 
                               BlogEntryService blogService)
        {
            this.m_pageService = pageService;
            this.m_settingService = settingService;
            this.m_log = log;
            this.m_blogService = blogService;
        }

        #region Posts

        [CurrentUserFilter]
        public JsonResult CreatePostAlias(string title, string categoryId)
        {
            if (string.IsNullOrEmpty(title) && string.IsNullOrEmpty(categoryId))
                title = "invalid value";
            var entry = new BlogEntry
            {
                Header = title,
                CategoryId = Convert.ToInt32(categoryId),
                Visible = false,
                Content = " ",
                HeaderUrl = "abc"
            };
            m_blogService.CreateEntry(entry);
            entry.HeaderUrl = CreateAliasExtensions.CreateAlias(title, entry.Id);
            m_blogService.Update(entry);
            var url = Url.Action("Entry", "Blog", new { area = "", category = m_blogService.GetCategoryById(Convert.ToInt32(categoryId)).CategoryName.ToLower(), id =  entry.HeaderUrl});
            return Json(new { alias = entry.HeaderUrl, id = entry.Id, url = url });
        }

        [CurrentUserFilter]
        public JsonResult UpdatePostAlias(int id, string alias)
        {
            try
            {
                var post = m_blogService.GetById(id); 
                
                if (null == post || string.IsNullOrEmpty(alias))
                    throw new NullReferenceException("Page was not found, or user input is empty.");
                
                SearchService.ClearLuceneIndexRecord(post.Alias);
                
                var paths = alias.Split('/');
                post.HeaderUrl = CreateAliasExtensions.CreateAlias(paths.Length > 0 ? paths[paths.Length - 1] : paths[0], id);
                
                m_blogService.Save(post);
                
                var categoryName = post.Category == null ? "main" : post.Category.CategoryName.ToLower();
                var url = Url.Action("Entry", "Blog", new { area = "", category = categoryName, id = post.HeaderUrl });
                
                return Json(new { alias = post.HeaderUrl, id = post.Id, url = url });
            }
            catch (Exception ex)
            {
                m_log.Exception(ex);
                throw;
            }
        }

        #endregion

        #region Pages

        [CurrentUserFilter]
        public JsonResult CreateAlias(string title)
        {
            if (string.IsNullOrEmpty(title))
                title = "invalid value";

            var page = new CmsPage();
            page.PageTitle = title;
            page.CategoryId = 1;
            page.StatusId = (int)StatusCode.Draft;
            m_pageService.CreateEntry(page);

            page.Alias = CreateAliasExtensions.CreateAlias(title, null);
            m_pageService.Save(page);

            return Json(new { alias = page.Alias, id = page.Id, created = page.CreatedAt.ToString(), modified = page.ModifiedAt.ToString() });
        }

        [CurrentUserFilter]
        public JsonResult UpdateAlias(int id, string alias)
        {
            try
            {
                CmsPage page = m_pageService.GetById(id);
                if (null == page || string.IsNullOrEmpty(alias))
                    throw new NullReferenceException("Page was not found, or user input is empty.");

                SearchService.ClearLuceneIndexRecord(page.Alias);

                page.Alias = CreateAliasExtensions.CreateAlias(alias, null);
                m_pageService.Save(page);
                return Json(new { alias = page.Alias, id = page.Id });
            }
            catch (Exception ex)
            {
                m_log.Exception(ex);
                throw;
            }
        }

        [HttpPost]
        public ActionResult SetRatingFixed(string number, string id, string type)
        {
            try
            {
                var rate = Convert.ToInt32(number);
                var objId = Convert.ToInt32(id);
                double rated = ((double)rate/20)*5;
                if (type == "page")
                {
                    var ar = m_pageService.IncrementPageRating(rated, objId, User.Identity.Name);
                    return Json(new { result = "success", success = true, totalRating = ConvertDoubleToFixed(ar.AverageRating).ToString("f"), totalPeople = ar.TotalRaters.ToString("d") });
                }
                else
                {
                    var ar = m_blogService.IncrementPostRating(rated, objId, User.Identity.Name);
                    return Json(new { result = "success", success = true, totalRating = ConvertDoubleToFixed(ar.AverageRating).ToString("f"), totalPeople = ar.TotalRaters.ToString("d") });
                }
            }
            catch (Exception ex)
            {
                return Json(new { result = "error", success = false, message = ex.Message });
            }
        }

        [HttpPost]
        public ActionResult IsRated(string name, string type, string id)
        {
            try
            {
                var objId = Convert.ToInt32(id);
                if (type == "page")
                {
                    var res = m_pageService.IsRatedBefore(objId, name);
                    return Json(new {result = "ok", success = true, rated = res});
                }
                else if (type == "post")
                {
                    var res = m_blogService.IsRatedBefore(objId, name);
                    return Json(new {result = "ok", success = true, rated = res});
                }
                else
                {
                    return Json(new { result = "error", success = false });    
                }
                
            }
            catch(Exception ex)
            {
                return Json(new { result = "error", success = false, message = ex.Message });
            }
        }

        private static double ConvertDoubleToFixed(double from)
        {
            double cel = Math.Truncate(from);
            double ost = from - cel;
            double del = Math.Truncate(ost / 0.25);
            return cel + (del + (ost % 0.25 > 0.125 ? 1 : 0)) * 0.25;
        }

        //TODO: Move this to Pages controller
        [HttpPost]
        public JsonResult AddPageComment(int entryId, string name, string email, string comment, int? replyId)
        {
            if (name != null)
            {
                var newComment = new CmsPageComment()
                {
                    PageId = entryId,
                    Name = name,
                    Email = email,
                    Comment = comment,
                    ParentId = replyId
                };

                m_pageService.AddComment(newComment);
                return Json(new { result = true, id = newComment.Id, hash = newComment.Email.ToLowerInvariant().EncryptMD5().ToLowerInvariant() });
            }
            return Json(new { result = false });
        }
        //TODO: Move this to Blog controller
        [HttpPost]
        public JsonResult AddPostComment(int entryId, string name, string email, string comment, int? replyId)
        {
            if (name != null)
            {
                var newComment = new BlogEntryComment()
                {
                    BlogEntryId = entryId,
                    Name = name,
                    Email = email,
                    Comment = comment,
                    ParentId = replyId
                };

                m_blogService.AddComment(newComment);
                return Json(new { result = true, id = newComment.Id, hash = newComment.Email.ToLowerInvariant().EncryptMD5().ToLowerInvariant() });
            }
            return Json(new { result = false });
        }
        
        public string FreeHtml(string htmlKey)
        {
            return m_settingService.GetSettingValue(htmlKey, HttpContext.Cache);
        }

        #endregion

    }
}